package com.zjw.common.handler;

import com.study.common.Result;
import org.springframework.core.MethodParameter;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.method.support.ModelAndViewContainer;

public class WrapReturnValueHandler implements HandlerMethodReturnValueHandler {
    /**
     * 采用装饰者模式
     */
    private final HandlerMethodReturnValueHandler delegate;

    public WrapReturnValueHandler(HandlerMethodReturnValueHandler delegate) {
        this.delegate = delegate;
    }

    @Override
    public boolean supportsReturnType(MethodParameter returnType) {
        return this.delegate.supportsReturnType(returnType);
    }

    @Override
    public void handleReturnValue(Object returnValue, MethodParameter returnType,
                                  ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {
        // 1. 对所有返回值进行包装处理, 适用于新项目
        returnValue = new Result(returnValue);
        this.delegate.handleReturnValue(returnValue, returnType, mavContainer, webRequest);
        /**
        // 2. 兼容现有项目, 对某些类型(Result)的返回值不处理,
        if (!(returnValue instanceof Result)) {
            returnValue = new Result(returnValue);
        }
        this.delegate.handleReturnValue(returnValue, returnType, mavContainer, webRequest);

        // 3. 兼容现有项目, 只对标记了注解的类/方法的返回值进行处理
        boolean needHandleReturnValue = AnnotatedElementUtils.hasAnnotation(returnType.getContainingClass(), JsonResult.class) ||
                returnType.hasMethodAnnotation(JsonResult.class);
        if (needHandleReturnValue) {
            returnValue = new Result(returnValue);
        }
        this.delegate.handleReturnValue(returnValue, returnType, mavContainer, webRequest);

        // 4. 忽略某些方法对返回值的处理
        boolean ignore = AnnotatedElementUtils.hasAnnotation(returnType.getContainingClass(), JsonResult.class) ||
                returnType.hasMethodAnnotation(JsonResult.class);
        if (!ignore) {
            returnValue = new Result(returnValue);
        }
        this.delegate.handleReturnValue(returnValue, returnType, mavContainer, webRequest);
         **/
    }
}
